﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using System.Globalization;

namespace Brain
{
    public class SerializationData
    {
        public List<SerializationDataObject> Data;

        public string TypeName { get; set; }

        public SerializationData()
        {
            Data = new List<SerializationDataObject>();
        }

        public void AddData(string key, object data)
        {
            if (key == "ParentType")
            {
                this.TypeName = data.ToString();
            }
            else
            {
                Data.Add(new SerializationDataObject(key, data));
            }
        }
        public void AddData(string key, object data, int index)
        {
            Data.Add(new SerializationDataObject(key + index, data));
        }
        public void AddData(string key, object data, string add)
        {
            Data.Add(new SerializationDataObject(key + add, data));
        }

        public T GetData<T>(string key)
        {
            for (int i = 0; i < Data.Count; i++)
            {
                SerializationDataObject obj = Data[i];
                if (obj.Key == key)
                {
                    if (obj.Object == "null")
                    {
                        return default(T);
                    }
                    return (T)obj.Object;
                }
            }
            return default(T);
        }
        public T GetData<T>(string key, int index)
        {
            for (int i = 0; i < Data.Count; i++)
            {
                SerializationDataObject obj = Data[i];
                if (obj.Key == key + index)
                {
                    if (obj.Object == "null")
                    {
                        return default(T);
                    }
                    return (T)obj.Object;
                }
            }
            return default(T);
        }

        public T GetData<T>(string key, string add)
        {
            for (int i = 0; i < Data.Count; i++)
            {
                SerializationDataObject obj = Data[i];
                if (obj.Key == key + add)
                {
                    if (obj.Object == "null")
                    {
                        return default(T);
                    }
                    return (T)obj.Object;
                }
            }
            return default(T);
        }

        private static char Sep = ':';
        public void TransformDataInString()
        {
            for (int i =0; i < Data.Count; i++)
            {
                SerializationDataObject pair = Data[i];
                object ob = pair.Object;

                if (ob is float)
                {
                    float data = (float)ob;
                    pair.Object = "float:" + data.ToString(CultureInfo.InvariantCulture);
                }
                else if (ob is double)
                {
                    double data = (double)ob;
                    pair.Object = "double:" + data.ToString(CultureInfo.InvariantCulture);
                }
                else if (ob is decimal)
                {
                    decimal data = (decimal)ob;
                    pair.Object = "decimal:" + data.ToString(CultureInfo.InvariantCulture);
                }
                else if (ob is Vector2)
                {
                    Vector2 data = (Vector2)ob;
                    pair.Object = "vector2:" + data.X.ToString(CultureInfo.InvariantCulture) + Sep + data.Y.ToString(CultureInfo.InvariantCulture);
                }
                else if (ob is Vector3)
                {
                    Vector3 data = (Vector3)ob;
                    pair.Object = "vector3:" +
                        data.X.ToString(CultureInfo.InvariantCulture) + Sep +
                        data.Y.ToString(CultureInfo.InvariantCulture) + Sep +
                        data.Z.ToString(CultureInfo.InvariantCulture);
                }
                else if (ob is Vector4)
                {
                    Vector4 data = (Vector4)ob;
                    pair.Object = "vector4:" +
                        data.X.ToString(CultureInfo.InvariantCulture) + Sep +
                        data.Y.ToString(CultureInfo.InvariantCulture) + Sep +
                        data.Z.ToString(CultureInfo.InvariantCulture) + Sep +
                        data.W.ToString(CultureInfo.InvariantCulture);
                }
                else if (ob is Color)
                {
                    Color data = (Color)ob;
                    pair.Object = "color:" +
                        data.R.ToString(CultureInfo.InvariantCulture) + Sep +
                        data.G.ToString(CultureInfo.InvariantCulture) + Sep +
                        data.B.ToString(CultureInfo.InvariantCulture) + Sep +
                        data.A.ToString(CultureInfo.InvariantCulture);
                }
                else if (ob is byte)
                {
                    byte data = (byte)ob;
                    pair.Object = "byte:" + data.ToString(CultureInfo.InvariantCulture);
                }
                else if (ob is sbyte)
                {
                    sbyte data = (sbyte)ob;
                    pair.Object = "sbyte:" + data.ToString(CultureInfo.InvariantCulture);
                }
                else if (ob is short)
                {
                    short data = (short)ob;
                    pair.Object = "short:" + data.ToString(CultureInfo.InvariantCulture);
                }
                else if (ob is ushort)
                {
                    ushort data = (ushort)ob;
                    pair.Object = "ushort:" + data.ToString(CultureInfo.InvariantCulture);
                }
                else if (ob is int)
                {
                    int data = (int)ob;
                    pair.Object = "int:" + data.ToString(CultureInfo.InvariantCulture);
                }
                else if (ob is uint)
                {
                    uint data = (uint)ob;
                    pair.Object = "uint:" + data.ToString(CultureInfo.InvariantCulture);
                }
                else if (ob is long)
                {
                    long data = (long)ob;
                    pair.Object = "long:" + data.ToString(CultureInfo.InvariantCulture);
                }
                else if (ob is ulong)
                {
                    ulong data = (ulong)ob;
                    pair.Object = "ulong:" + data.ToString(CultureInfo.InvariantCulture);
                }
                else if (ob is bool)
                {
                    bool data = (bool)ob;
                    pair.Object = "bool:" + data.ToString(CultureInfo.InvariantCulture);
                }
                else if (ob is string)
                {
                    string data = (string)ob;
                    pair.Object = "string:" + data.ToString(CultureInfo.InvariantCulture);
                }
                else if (ob is Rectangle)
                {
                    Rectangle data = (Rectangle)ob;
                    pair.Object = "rectangle:"
                        + data.X.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.Y.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.Width.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.Height.ToString(CultureInfo.InvariantCulture);
                }
                else if (ob is BoundingBox)
                {
                    BoundingBox data = (BoundingBox)ob;
                    pair.Object = "bbox:"
                        + data.Min.X.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.Min.Y.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.Min.Z.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.Max.X.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.Max.Y.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.Max.Z.ToString(CultureInfo.InvariantCulture);
                }
                else if (ob is BoundingSphere)
                {
                    BoundingSphere data = (BoundingSphere)ob;
                    pair.Object = "bsphere:"
                        + data.Center.X.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.Center.Y.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.Center.Z.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.Radius.ToString(CultureInfo.InvariantCulture);
                }
                else if (ob is Matrix)
                {
                    Matrix data = (Matrix)ob;
                    pair.Object = "matrix:"
                        + data.M11.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.M12.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.M13.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.M14.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.M21.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.M22.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.M23.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.M24.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.M31.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.M32.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.M33.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.M34.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.M41.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.M42.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.M43.ToString(CultureInfo.InvariantCulture) + Sep
                        + data.M44.ToString(CultureInfo.InvariantCulture);

                }
                else if (ob is Enum)
                {
                    int data = (int)ob;
                    pair.Object = "enum:" + data.ToString(CultureInfo.InvariantCulture);
                }
            }
        }


        public void TransformStringInData()
        {
            for (int i = 0; i < Data.Count; i++)
            {
                SerializationDataObject pair = Data[i];
                string ob = pair.Object as string;
                string[] splitted = ob.Split(':');

                if (ob.StartsWith("float"))
                {
                    pair.Object = float.Parse(splitted[1], CultureInfo.InvariantCulture);
                }
                else if (ob.StartsWith("double"))
                {
                    pair.Object = double.Parse(splitted[1], CultureInfo.InvariantCulture);
                }
                else if (ob.StartsWith("decimal"))
                {
                    pair.Object = double.Parse(splitted[1], CultureInfo.InvariantCulture);
                }
                else if (ob.StartsWith("vector2"))
                {
                    Vector2 data = new Vector2();
                    data.X = float.Parse(splitted[1], CultureInfo.InvariantCulture);
                    data.Y = float.Parse(splitted[2], CultureInfo.InvariantCulture);
                    pair.Object = data;
                }
                else if (ob.StartsWith("vector3"))
                {
                    Vector3 data = new Vector3();
                    data.X = float.Parse(splitted[1], CultureInfo.InvariantCulture);
                    data.Y = float.Parse(splitted[2], CultureInfo.InvariantCulture);
                    data.Z = float.Parse(splitted[3], CultureInfo.InvariantCulture);
                    pair.Object = data;
                }
                else if (ob.StartsWith("vector4"))
                {
                    Vector4 data = new Vector4();
                    data.X = float.Parse(splitted[1], CultureInfo.InvariantCulture);
                    data.Y = float.Parse(splitted[2], CultureInfo.InvariantCulture);
                    data.Z = float.Parse(splitted[3], CultureInfo.InvariantCulture);
                    data.W = float.Parse(splitted[4], CultureInfo.InvariantCulture);
                    pair.Object = data;
                }
                else if (ob.StartsWith("color"))
                {
                    Color data = new Color();
                    data.R = byte.Parse(splitted[1], CultureInfo.InvariantCulture);
                    data.G = byte.Parse(splitted[2], CultureInfo.InvariantCulture);
                    data.B = byte.Parse(splitted[3], CultureInfo.InvariantCulture);
                    data.A = byte.Parse(splitted[4], CultureInfo.InvariantCulture);
                    pair.Object = data;
                }
                else if (ob.StartsWith("byte"))
                {
                    pair.Object = byte.Parse(splitted[1], CultureInfo.InvariantCulture);
                }
                else if (ob.StartsWith("sbyte"))
                {
                    pair.Object = sbyte.Parse(splitted[1], CultureInfo.InvariantCulture);
                }
                else if (ob.StartsWith("short"))
                {
                    pair.Object = short.Parse(splitted[1], CultureInfo.InvariantCulture);
                }
                else if (ob.StartsWith("ushort"))
                {
                    pair.Object = ushort.Parse(splitted[1], CultureInfo.InvariantCulture);
                }
                else if (ob.StartsWith("int"))
                {
                    pair.Object = int.Parse(splitted[1], CultureInfo.InvariantCulture);
                }
                else if (ob.StartsWith("uint"))
                {
                    pair.Object = uint.Parse(splitted[1], CultureInfo.InvariantCulture);
                }
                else if (ob.StartsWith("long"))
                {
                    pair.Object = long.Parse(splitted[1], CultureInfo.InvariantCulture);
                }
                else if (ob.StartsWith("ulong"))
                {
                    pair.Object = ulong.Parse(splitted[1], CultureInfo.InvariantCulture);
                }
                else if (ob.StartsWith("bool"))
                {
                    pair.Object = bool.Parse(splitted[1]);
                }
                else if (ob.StartsWith("string"))
                {
                    string value = "";
                    for (int x = 1; x < splitted.Length; x++)
                    {
                        string s = splitted[x];
                        value += s;
                        if (x + 1 < splitted.Length)
                        {
                            value += Sep;
                        }
                    }

                    pair.Object = value;
                }
                else if (ob.StartsWith("rect"))
                {
                    pair.Object = new Rectangle(
                        int.Parse(splitted[1], CultureInfo.InvariantCulture),
                        int.Parse(splitted[2], CultureInfo.InvariantCulture),
                        int.Parse(splitted[3], CultureInfo.InvariantCulture),
                        int.Parse(splitted[4], CultureInfo.InvariantCulture));
                }
                else if (ob.StartsWith("bbox"))
                {
                    pair.Object = new BoundingBox(
                        new Vector3(
                            float.Parse(splitted[1], CultureInfo.InvariantCulture),
                            float.Parse(splitted[2], CultureInfo.InvariantCulture),
                            float.Parse(splitted[3], CultureInfo.InvariantCulture)),
                        new Vector3(
                            float.Parse(splitted[4], CultureInfo.InvariantCulture),
                            float.Parse(splitted[5], CultureInfo.InvariantCulture),
                            float.Parse(splitted[6], CultureInfo.InvariantCulture)));
                }
                else if (ob.StartsWith("bsphere"))
                {
                    pair.Object = new BoundingSphere(
                        new Vector3(
                            float.Parse(splitted[1], CultureInfo.InvariantCulture),
                            float.Parse(splitted[2], CultureInfo.InvariantCulture),
                            float.Parse(splitted[3], CultureInfo.InvariantCulture)),
                            float.Parse(splitted[4], CultureInfo.InvariantCulture));
                }
                else if (ob.StartsWith("matrix"))
                {
                    pair.Object = new Matrix(
                        float.Parse(splitted[1], CultureInfo.InvariantCulture),
                        float.Parse(splitted[2], CultureInfo.InvariantCulture),
                        float.Parse(splitted[3], CultureInfo.InvariantCulture),
                        float.Parse(splitted[4], CultureInfo.InvariantCulture),
                        float.Parse(splitted[5], CultureInfo.InvariantCulture),
                        float.Parse(splitted[6], CultureInfo.InvariantCulture),
                        float.Parse(splitted[7], CultureInfo.InvariantCulture),
                        float.Parse(splitted[8], CultureInfo.InvariantCulture),
                        float.Parse(splitted[9], CultureInfo.InvariantCulture),
                        float.Parse(splitted[10], CultureInfo.InvariantCulture),
                        float.Parse(splitted[11], CultureInfo.InvariantCulture),
                        float.Parse(splitted[12], CultureInfo.InvariantCulture),
                        float.Parse(splitted[13], CultureInfo.InvariantCulture),
                        float.Parse(splitted[14], CultureInfo.InvariantCulture),
                        float.Parse(splitted[15], CultureInfo.InvariantCulture),
                        float.Parse(splitted[16], CultureInfo.InvariantCulture));
                }
                else if (ob.StartsWith("enum"))
                {
                    int value = int.Parse(splitted[1], CultureInfo.InvariantCulture);
                    pair.Object = value;
                }
            }
        }
    }
}
